#ifndef __C_ADVANCED_MESH_COLLISION_H_INCLUDED__
#define __C_ADVANCED_MESH_COLLISION_H_INCLUDED__

#include <irrlicht.h>
using namespace irr;

class CAdvancedMeshCollision
{
public: 
	//! Constructor: specify the mesh and scene node
	CAdvancedMeshCollision(irr::scene::IMesh* mesh, 
				   irr::scene::ISceneNode* node);

	//! Constructor: Try to automatically find the right mesh from the scenenode
	CAdvancedMeshCollision(irr::scene::ISceneNode* node);

	//! Check if there is a collision with any meshbuffers in the mesh/SceneNode
	//! associated with the current CMeshCollision instance.
	bool isRayCollideMesh(const irr::core::line3d<f32>& ray,
						irr::core::vector3df& outCollisionPoint,
						irr::core::triangle3df& outTriangle);
						
	bool isRayCollideMesh(const irr::core::line3d<f32>& ray,
						irr::core::vector3df& outCollisionPoint,
						irr::core::triangle3df& outTriangle,
						u32& color1);

	irr::scene::ISceneNode* getSceneNode() { return SceneNode; }
	
	void GetTriangles(irr::core::array<irr::core::triangle3df>& triangles);
	
	void GetTriangle(irr::core::triangle3df& triangle, const irr::scene::IMeshBuffer* buf, const u16* const indices, s32 start);
	//void GetTriangle(irr::core::triangle3df& triangle, irr::video::S3DVertexComponentArrays::SAccessorVector3df& accessor, const u16* const indices, s32 start);
	//void GetTriangle(irr::core::triangle3df& triangle, irr::video::S3DVertexComponentArrays::SAccessorVector3ds& accessor, const u16* const indices, s32 start);
	void TransformTriangle(irr::core::triangle3df& triangle);
	
	u32 GetInterpolatedColor(const irr::core::vector3df& collisionPoint, const irr::core::triangle3df& collisionTriangle,
							u32 color1, u32 color2, u32 color3);

	//u32 GetColor(s32 bufindex, irr::video::S3DVertexComponentArrays *pVertices,
	//								const u16* const indices, s32 start,
	//								const irr::core::vector3df& outCollisionPoint,
	//								const irr::core::triangle3df& outTriangle);

	bool isHidden() { return m_isHidden; }
	void hide() { m_isHidden = true; }
	void show() { m_isHidden = false; }
protected:
	//! Check collision between a line and a tringle with some sortcuts, 
	//! must be called by 'isRayCollideMesh'
	bool checkCollision(const irr::core::triangle3df &triangle, 
						const irr::core::line3df &line, 
						irr::core::vector3df &outIntersection,
						bool checkFacing = false) const;

	//! Pointer to the scenenode, we'll use it's transformation matrix
	irr::scene::ISceneNode* SceneNode;

	//! Pointer to the mesh object to check against.
	irr::scene::IMesh* Mesh;

	//! Tell if the mesh is in worldspace. This will tells us if we have to 
	//! modify the ray to be in object-space.
	bool MeshIsInWorldspace;
	
	//! working variables used as local buffer for sortcuts in 'checkCollision'
	mutable irr::core::vector3df Min;
	mutable irr::core::vector3df Max;
	mutable f32 RayLength;
	mutable irr::core::vector3df RayVect;
	
	bool isStoringColors;
	bool m_isHidden;
};
#endif
